#ifndef DW_GRAPHICS_MODEL_H
# define DW_GRAPHICS_MODEL_H

namespace dw
{
namespace graphics
{

class Material;
class Node;
class Mesh;
class Light;
class Camera;

class Model
{
// Constructors
public:
	
																	Model(const std::string& name = "");

																	~Model();

// Methods
public:

	const std::string& getName() const { return _name; }

	unsigned getNumMaterials() const { return static_cast< unsigned >(_materialByName.size()); }

	Material* getMaterial(const std::string& name);

	unsigned getMaterialCount() const { return static_cast< unsigned >(_materialByName.size()); }

	unsigned getMeshCount() const { return static_cast< unsigned >(_meshes.size()); }

	Node* getHierarchy() const { return _hierarchy; }



	void setHierarchy(Node* node) { _hierarchy = node; }



	void addMaterial(Material* material);

	void addMesh(Mesh* mesh);

	void addLight(Light* light);

	void addCamera(Camera* camera);



	void removeMaterial(const Material* material);

	void removeMesh(const Mesh* mesh);

	void removeLight(const Light* light);

	void removeCamera(const Camera* camera);



	static Model* fromStream(std::istream& is);

	static Model* fromFile(const std::string& filename);



	/// Render the model
	virtual void draw();

// Typedefs
protected:

	typedef std::map<std::string, Material*>			MaterialNameMap;

	//typedef std::map<std::string, Object*>				ObjectNameMap;

	//typedef std::multimap<Object::Type, Object*>	ObjecTypeMap;


	typedef MaterialNameMap::iterator MaterialIterator;

// Fields
protected:

	/// Name of this model
	std::string _name;
	/// Root of the model's node hierarchy 
	Node* _hierarchy;
	/// Materials of the model referenced by name
	MaterialNameMap _materialByName;
	/// Objects of the model referenced by type
	//ObjectTypeMap _objectByType;

	std::vector< Mesh* >							_meshes;

	std::vector< Camera* >						_cameras;

	std::vector< Light* >							_lights;

private:

	///	iostream compatible serialization
	friend
	std::ostream& operator<<(std::ostream& os, Model& model);
	
	///	iostream compatible deserialization
	friend
	std::istream& operator>>(std::istream& is, Model& model);
};

} // namespace graphics
} // namespace dw

#endif // !DW_GRAPHICS_MODEL_H
